package com.cheng.spider.component;

import com.cheng.spider.analyze.ResponseAnalyzer;
import com.cheng.spider.constant.MimeType;
import com.cheng.spider.custom.UrlSource;
import com.cheng.spider.extract.DataResolver;
import com.cheng.spider.extract.novel.NovelWriter;
import com.cheng.spider.request.HttpTransaction;
import com.cheng.spider.request.Requester;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpRequestBase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class AbstractSpider implements Runnable {

    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSpider.class);

    private Requester requester;

    private ResponseAnalyzer responseAnalyzer;

    private DataResolver dataResolver;

    private UrlSource urlSource;

    public AbstractSpider() {
        urlSource = initUrlSource();
        urlSource.fullQueue();
        requester = initRequester();
        responseAnalyzer = initResponseAnalyzer();
        dataResolver = initDataResolver();
    }

    private void boot() {
        while (!urlSource.isEmpty()) {
            String url = urlSource.getUrl();
            if (url != null) {
                beforeConsumeUrl();
                consumeUrl(url);
                afterConsumeUrl();
            }
            try {
                Thread.sleep(4 * 1000);
            } catch (InterruptedException e) {
                LOGGER.error("线程异常，当前URL：" + url);
                e.printStackTrace();
            }
        }
    }

    private void consumeUrl(String url) {
        HttpTransaction transaction = null;
        HttpRequestBase request = null;
        HttpResponse response = null;
        try {
            transaction = requester.execute(url);
            request = transaction.getRequest();
            response = transaction.getResponse();
            MimeType mimeType = responseAnalyzer.analyze(response);
            dataResolver.resolve(response, mimeType);
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("消费Url过程出现异常：" + url);
        } finally {
            if (request != null) {
                request.releaseConnection();
            }
        }
    }

    @Override
    public void run() {
        beforeBoot();
        boot();
        afterBoot();
    }

    protected void beforeBoot() {
    }

    protected void afterBoot() {
        //TODO 这句代码不应该在这里
        if (NovelWriter.inited()) {
            NovelWriter.close();
        }
    }

    protected void beforeConsumeUrl() {
    }

    protected void afterConsumeUrl() {
    }

    protected abstract UrlSource initUrlSource();

    protected abstract DataResolver initDataResolver();

    protected abstract ResponseAnalyzer initResponseAnalyzer();

    protected abstract Requester initRequester();

}
